#-*- coding:utf-8 -*-
'''
日期： 2013-3-19
@作者:  Monk
'''
import os,urllib,datetime,cgi,time,math,sys,md5,base64,email
#import google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler
from google.appengine.ext import webapp
from google.appengine.ext import blobstore
from google.appengine.ext.blobstore import BlobInfo,BlobKey,CLOUD_STORAGE_OBJECT_HEADER
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
####################基本程序#####################################
class BaseController(webapp.RequestHandler):
    #要想模板中设置的变量
    __vars__ = {}
    #显示模板
    def display(self,finename,dir = None):
        user = users.get_current_user()
        if not user:
            self.assign("loginurl", users.create_login_url("/"))
        else:
            self.assign("logouturl", users.create_logout_url("/"))
            self.assign("isadmin", users.is_current_user_admin())#是否是管理员装好
            self.assign("user", user)
        path = os.path.join(os.path.dirname(__file__),"views", finename + '.html')
        if not dir is None:
            path = os.path.join(os.path.dirname(__file__),"views",dir, finename + '.html')
        #self.response.out.write(path)
        self.response.out.write(template.render(path, self.__vars__))
    #想模板中添加变量
    def assign(self,k,v):
        self.__vars__[k] = v
    def categorylist(self):
        sql = CategoryModel.all()
        results = sql.fetch(1000)
        #print results
        self.assign("categorylist", results)
    #处理分页
    def pages(self,page = 1,sum = 0 ,pagesize = 20,ps = 10):
        page = int(page)
        sum = int(sum)
        pagesize = int(pagesize)
        ps = int(ps)
        pagedata = {}
        sumpage = 0
        pagedata['page'] = page
        if sum > 0:
            sumpage = int(math.ceil(float(sum)/pagesize))#总行数
            if sumpage > ps:
                pagedata['start'] = int(math.floor(float(page)/ps)*ps)
                pagedata['end'] = int(math.floor(float(page)/ps)*ps + ps)
                #self.response.out.write("page = %d ps =%d" %(page,ps))
                if page > ps:
                    pagedata['per'] = int(math.floor(float(page)/ps-1)*ps + 1)
                if math.ceil(float(page)/ps) < sumpage:
                    pagedata['next'] = int(math.floor(float(page)/ps +1) *ps + 1)
            else:
                pagedata['start'] = 1
                pagedata['end'] = sumpage
            pagedata['sum'] = sum
            pagedata['sumpage'] = sumpage
            pagedata['list'] = range(pagedata['start'],(pagedata['end']))
            self.assign("pages", pagedata)
            #self.response.out.write(self.__vars__)
        else:
            pass
#下载大文件
class FileDown(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, resource):
        resource = str(urllib.unquote(resource))
        blob_info = blobstore.BlobInfo.get(resource)
        #self.response.headers['Content-Type'] = 'image/jpeg'
        #self.response.headers['Content-Type'] = "image/" + blob_info.filename[blob_info.filename.rindex(".")+1 :]
        #r = blob_info.open()
        #self.response.out.write(r.read())
        self.send_blob(blob_info)
#######################数据库层相关的##########################################
#日志相关的数据操作
class BlogModel(db.Model):
    btitle = db.StringProperty(required = True)#日志标题
    bbody = db.TextProperty(required = True)#日志内容
    bdesc = db.TextProperty(required = True)#日志内容    
    bcategory = db.StringProperty(required = True)#日志的分类
    breads = db.IntegerProperty(required = True)#阅读次数
    breplys = db.IntegerProperty(required = True)#日志的回复次数
    byear = db.IntegerProperty(required = True)#发布年份
    bmonth = db.IntegerProperty(required = True)#发布月份
    bday = db.IntegerProperty(required = True)#发布的日期
    baddtime = db.DateTimeProperty(required = True)#发布的时间
    bedittime = db.DateTimeProperty(auto_now_add=True)#最后修改的时间
    bhasattachment = db.BooleanProperty(required = True)#是否含附件
#日志的分类信息
class CategoryModel(db.Model):
    cname = db.StringProperty(required = True)#日志类别
    blogs = db.IntegerProperty()#日志的总数
#上传文件相关的数据库操作
class AttachmentModel(db.Model):
    #大文件的key
    blobkey = db.StringProperty(required = True)
    #文件描述
    desc = db.StringProperty(required = True)
#上传的照片相关的操作
class ImgModle(db.Model):
    #大文件的key
    imgkey = db.StringProperty(required = True)
    #大文件的描述
    desc = db.StringProperty(required = True)
    
################编辑器相关的操作############################
#获取视频的信息
class GetMovie(BaseController):
    def post(self):
        key = cgi.escape(self.request.get("searchKey"))
        type = cgi.escape(self.request.get("videoType"))
        h = urllib.urlopen('http://api.tudou.com/v3/gw?method=item.search&appKey=myKey&format=json&kw='+key+'&pageNo=1&pageSize=20&channelId='+type+'&inDays=7&media=v&sort=s')
        self.response.out.write(h.readlines())
#远程抓取图片配置
class GetUploadUrl(BaseController):
    def get(self,key):
        self.response.out.write("var uploadurl='%s';" %(blobstore.create_upload_url('/' + key)))
#获取图片列表
class Images(BaseController):
    def get(self):
        q = ImgModle.all()
        list = q.fetch(q.count())
        st = ""
        for f in list:
            st += f.key() + "ue_separate_ue"
        self.response.out.write(st)
class GetRemoteImage(BaseController):
    def post(self):
        pass
#上传文件处理
class FileUp(blobstore_handlers.BlobstoreUploadHandler):  
    def post(self):
        ext = ( ".rar" , ".doc" , ".docx" , ".zip" , ".pdf" , ".txt" , ".swf" , ".wmv" )
        upload_files = self.get_uploads('upfile')
        blob_info = upload_files[0]
        #上传文件大小超过限制了
        if blob_info.size > 100000:
            pass
        info = os.path.split(blob_info.filename)
        fname = info[1];
        type = False
        for k in ext:
            if fname.rfind(k):
                type = k
                break
        #上传的文件是不允许的类型
        if type is False:
            pass
        self.response.write('{"url":"%s","fileType":"%s","original":"%s","state":"%s"}' % (blob_info.key(),type,fname,""))
        #self.redirect('/serve/%s' % blob_info.key())
#上传图片处理
class ImageUp(blobstore_handlers.BlobstoreUploadHandler):  
    def post(self):
        #print blobstore.create_upload_url('/upload')
        title = cgi.escape(self.request.get("pictitle"))
        ext = ( ".gif", ".png", ".jpg", ".jpeg", ".bmp" )
        upload_files = self.get_uploads('upfile')
        blob_info = upload_files[0]
        #上传文件大小超过限制了
        #if blob_info.size > 1000:
            #pass
        info = os.path.split(blob_info.filename)
        fname = info[1];
        type = False
        for k in ext:
            if fname.rfind(k):
                type = k
                break
        #上传的文件是不允许的类型
        #if type is False:
            #pass
        imgkey = "%s" % (blob_info.key())
        img = ImgModle(imgkey = cgi.escape(imgkey),desc = fname)
        #img.put()
        self.response.out.write('{"url":"/img/%s","title":"%s","original":"%s","state":"SUCCESS"}' % (blob_info.key(),fname,fname))
class ScrawlUp(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        action = cgi.escape(self.request.get("action"))
        if action == 'tmpImg':
            ext = ( ".gif", ".png", ".jpg", ".jpeg", ".bmp" )
            upload_files = self.get_uploads('upfile')
            blob_info = upload_files[0]
            #上传文件大小超过限制了
            if blob_info.size > 1000:
                pass
            info = os.path.split(blob_info.filename)
            fname = info[1];
            type = False
            for k in ext:
                if fname.rfind(k):
                    type = k
                    break
            #上传的文件是不允许的类型
            if type is False:
                pass
            self.response.out.write("<script>parent.ue_callback('/img/%s','SUCCESS')</script>" % (blob_info.key()))
        else:
            content = base64.decodestring(self.request.get("content"))
            _k = blobstore.create_upload_url("")
            _k = _k[1:]
            key = BlobKey(_k)
            filename = datetime.datetime.now()
            size = len(content)
            upload_content = email.message_from_string(content)
            gs_object_name = upload_content.get(CLOUD_STORAGE_OBJECT_HEADER, None)
            md5_hash = base64.urlsafe_b64decode(content)
            blob_info = BlobInfo(BlobKey(key), 
             {'blob_key': _k,
              'content_type': 'image/png',
              'creation': filename,
              'filename': str(filename),
              'size': size,
              'md5_hash': md5_hash,
              'gs_object_name': gs_object_name,
             })
            self.response.out.write("<script>parent.ue_callback('/img/%s','SUCCESS')</script>" % (blob_info.key()))
#########################一般用户相关的#####################################
#日志列表
class BlogList(BaseController):
    def get(self,page):
        if page:
            page = int(page)
        else:
            page = 1
        sql = BlogModel.all()
        sql.order("-baddtime")
        self.pages(page, sql.count(), 20, 10)
        if page < 1:
            page = 1
        rlist = sql.fetch(20,(page-1)*20 )
        self.assign("rlist", rlist)
        self.categorylist()
        self.display("bloglist", "user")
#查看日志
class BlogView(BaseController):
    def get(self,k):
        blog = BlogModel.get(k)
        blog.breads += 1
        blog.save()
        self.assign("blog", blog)
        self.categorylist()
        self.display("blogview", "user")
class BlogCategort(BaseController):
    def get(self,k,page):
        if page:
            page = int(page)
        else:
            page = 1
        sql = BlogModel.all()        
        sql.filter("bcategory =", str(k))
        sql.order("-baddtime")
        self.pages(page, sql.count(), 20, 10)
        if page < 1:
            page = 1
        #print k,page,sql.count()
        rlist = sql.fetch(20,(page-1)*20 )
        self.assign("rlist", rlist)
        self.categorylist()
        self.display("bloglist", "user")
###################管理员相关的#####################################
#日志列表
class AdminBlogList(BaseController):
    def get(self,page):
        if page:
            page = int(page)
        else:
            page = 1
        sql = BlogModel.all()
        self.pages(page, sql.count(), 20, 10)
        if page < 1:
            page = 1
        rlist = sql.fetch(20,(page-1)*20 )
        self.assign("rlist", rlist)
        self.display("bloglist", "admin")
#添加日志
class AdminBlogAdd(BaseController):
    def get(self):
        sql = CategoryModel.all()
        results = sql.fetch(1000)
        self.assign("results", results)
        self.display("blogadd","admin")
    def post(self):
        dt = datetime.datetime.now()
        bdesc = self.request.get("desc")
        if len(bdesc) > 500:
            bdesc = bdesc[0:500]
        blog = BlogModel(
                         btitle = self.request.get("btitle"),
                         bbody = self.request.get("bbody"),
                         bdesc = bdesc,
                         bcategory = self.request.get('category'),
                         breads = 0,
                         breplys = 0,
                         byear = dt.year,
                         bmonth = dt.month,
                         bday = dt.day,
                         baddtime = dt,
                         bhasattachment = False)
        if blog.put():
            cm = CategoryModel.get(self.request.get('category'))
            cm.blogs += 1
            cm.save()
            self.redirect("/admin/bloglist/1")
#修改日志
class AdminBlogEdit(BaseController):
    def get(self):
        pass
    def post(self):
        pass
#删除日志
class AdminBlogDel(BaseController):
    def get(self):
        pass
    def post(self):
        pass
#日志分类信息
class AdminCategory(BaseController):
    def get(self,ac):
        if ac == "add":
            cname = cgi.escape(self.request.get("cname"))
            ct = CategoryModel(cname = cname);
            ct.blogs = 0
            ct.put()
            self.redirect("/admin/category/")
        if ac == "del":
            ct = CategoryModel.get(cgi.escape(self.request.get("id")))
            ct.delete()
            self.redirect("/admin/category/")
        if ac == "edit":
            pass
        sql = CategoryModel.all()
        results = sql.fetch(1000)
        self.assign("results", results)
        self.display("category", "admin")
    
application = webapp.WSGIApplication(
                                     [
                                      ('/url/(.+)?',GetUploadUrl),                                   
                                      ('/(\d+)?',BlogList),#主页
                                      ('/blog/([^/]+)?',BlogView),#查看日志信息
                                      ('/blogcategort/([^/]+)/(\d+)?',BlogCategort),#查看分类
                                      #('',Index),#回复日志
                                      #上传相关
                                      ('/up/image',ImageUp),#上传图片
                                      ('/up/images/',Images),#上传图片
                                      ('/up/scrawl',ScrawlUp),#上传涂鸦
                                      ('/up/remoteimg',GetRemoteImage),#远程图片
                                      ('/up/fileup',FileUp),#上传文件
                                      ('/up/movie',GetMovie),#视频
                                      ('/up/images',ScrawlUp),#图片管理
                                      ('/img/([^/]+)?', FileDown),#图片查看
                                      ####管理员相关的##########
                                      ('/admin/blogadd', AdminBlogAdd),
                                      ('/admin/bloglist/([^/]+)?', AdminBlogList),
                                      ('/admin/category/([^/]+)?', AdminCategory),
                                      ],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()